package com.pic.mgt.syushin.executer;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.dao.DataAccessException;
import org.springframework.dao.DuplicateKeyException;

import com.pic.mgt.dao.syushin.SyushinBusinessTargetActionDao;
import com.pic.mgt.executer.IGXTypeExecutionException;
import com.pic.mgt.executer.TargetAction;
import com.pic.mgt.file.io.FileOperation;
import com.pic.mgt.log.IgxLog;
import com.pic.mgt.manager.business.ApInfoBean;
import com.pic.mgt.manager.business.BasicBusinessInfoBean;
import com.pic.mgt.syushin.unit.SyushinBusinessUnit;

public final class RealSyushinBusinessUnitExecuter extends SyushinBusinessUnitExecuter {
	// (送多方新增)
	private FileOperation fileOperation;
	
	public RealSyushinBusinessUnitExecuter(TargetAction targetAction,
						   CfmtAction cfmtAction) {
		super(targetAction, cfmtAction);
	}
	
	// (送多方新增)
	@Override
	protected void executeIGXBusinessTypeSpecify()
			throws IGXTypeExecutionException {
		BasicBusinessInfoBean basicBusinessInfoBean = this.businessManager.getBasicBusinessInfoBean(this.business.getBusinessName());
		if (null == basicBusinessInfoBean) {
			throw new IGXTypeExecutionException("Business '" + business.getBusinessName() + "' has not existed already.");
		}
		
		// 執行確認檔動作
		try {
			List<ApInfoBean> apInfoBeanList = basicBusinessInfoBean.getSyushinBusinessApList();
			for (ApInfoBean apInfoBean : apInfoBeanList) {
				// 執行資料新增 (syushin_business_target_action)
				insertSyushinTargetActionToDB(apInfoBean.getApName());
				
				// ********************** Log **********************
				if (IgxLog.messageLog.isDebugMode()) {
					IgxLog.messageLog.debug(this, 
							"Building Cfmt action for syushin business '{}' to AP '{}'.", super.unit
									.getUnitName(), apInfoBean.getApName());
				}
				// ********************** Log **********************
				
				cfmtAction.build(super.business, apInfoBean.getApFolder());
				
				// ********************** Log **********************
				if (IgxLog.messageLog.isDebugMode()) {
					IgxLog.messageLog.debug(this, 
							"Building Cfmt action for syushin business '{}' to AP '{}' completed.",
							super.unit.getUnitName(), apInfoBean.getApName());
				}
				// ********************** Log **********************
			}
			
			// 刪除確認檔
			this.fileOperation.deleteFile(super.business.getConfirmationFile());
		} catch (DataAccessException e1) {
			throw new IGXTypeExecutionException (
					"Syushin business '" + business.getUnitName() +
					"' execution failed in inserting syushin target action record to database (table: " +
					this.syushinBusinessTargetActionDao.getTableName() + ").",
					e1);
		} catch (BuildCfmtFileProcessException e) {
			throw new IGXTypeExecutionException(
					"Syushin business '" + business.getUnitName() +
					"' execution failed in building Cfmt file process", e);
		} catch (IOException e) {
			throw new IGXTypeExecutionException(
					"Syushin business '" + business.getUnitName() +
					"' execution failed in building Cfmt file process", e);
		}
	}
	
	/**
	 * 在 target action 動作完後，會新增資料到 syuhsin business target action table中。
	 * @throws DataAccessException
	 */
	// (送多方新增)
	private void insertSyushinTargetActionToDB(String apName) throws DataAccessException {
		try {
			Map<String, Object> insertValuesMap = getInsertValuesMap();
			// (送多方新增)
			insertValuesMap.put(SyushinBusinessTargetActionDao._apName, apName);
			this.syushinBusinessTargetActionDao.insertBasic(insertValuesMap);
		} catch (DuplicateKeyException e1) {
			// 若是在 Insert 資料時發生 Unique Key 重覆的例外
			
			/*
			 * 忽略之。此種情況可能發生的情形是在，當集信處理過程中發生失敗而中斷，
			 * 導致 syushin_business_target_action table 內已經存在有執行成功
			 * 的資料紀錄。這時再進行重新配信的動作時，便會發生資料有重覆 insert 的情形。
			 */
			// (送多方修改)
			this.syushinBusinessTargetActionDao.updateCreatingTimeByFilenameAndApName(
					new Timestamp(new Date().getTime()), super.business.getTargetFilename(), apName);
		} catch (DataAccessException e2) {
			throw e2;
		}
	}
	
	// (送多方新增)
	private Map<String, Object> getInsertValuesMap() {
		SyushinBusinessUnit syushinBusinessUnit =
						(SyushinBusinessUnit)super.business;
		
		Map<String, Object> insertValuesMap = new HashMap<String, Object>();
		
		insertValuesMap.put(SyushinBusinessTargetActionDao._unitName, syushinBusinessUnit.getUnitName());
		insertValuesMap.put(SyushinBusinessTargetActionDao._terminalId, syushinBusinessUnit.getTerminalID());
		insertValuesMap.put(SyushinBusinessTargetActionDao._fileName, syushinBusinessUnit.getTargetFilename());
		insertValuesMap.put(SyushinBusinessTargetActionDao._fileSize, syushinBusinessUnit.getTargetFileSize());
		
		return insertValuesMap;
	}
	
	@Override
	// (送多方新增)
	protected List<ApInfoBean> getSyncApList() {
		BasicBusinessInfoBean basicBusinessInfoBean = this.businessManager.getBasicBusinessInfoBean(this.business.getBusinessName());
		if (null != basicBusinessInfoBean) {
			return basicBusinessInfoBean.getSyushinBusinessApList();
		}
		else {
			return null;
		}
	}
	
	// --- getter and setter ---
	
	// (送多方新增)
	public void setFileOperation(FileOperation fileOperation) {
		this.fileOperation = fileOperation;
	}
}
